package com.tuda.system.service.impl;

import com.github.pagehelper.util.StringUtil;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.gson.Gson;
import com.tuda.common.core.domain.R;
import com.tuda.common.core.domain.entity.SysUser;
import com.tuda.common.enums.OrderPayType;
import com.tuda.common.enums.OrderType;
import com.tuda.common.pay.common.bean.PayOrder;
import com.tuda.common.pay.wx.WeixinPayConfig;
import com.tuda.common.pay.wx.bean.WxTransactionType;
import com.tuda.common.utils.EntityConvertUtils;
import com.tuda.common.utils.RedisUtil;
import com.tuda.common.utils.StringUtils;
import com.tuda.common.utils.ToolUtil;
import com.tuda.system.domain.TudaAppletUser;
import com.tuda.system.domain.TudaOrder;
import com.tuda.system.domain.TudaOrderTransfer;
import com.tuda.system.mapper.TudaAppletUserMapper;
import com.tuda.system.mapper.TudaOrderMapper;
import com.tuda.system.mapper.TudaOrderTransferMapper;
import com.tuda.system.model.param.*;
import com.tuda.system.model.result.*;
import com.tuda.system.service.ISysUserService;
import com.tuda.system.service.ITudaOrderRecordService;
import com.tuda.system.service.IUserOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.*;

/**
 * @ClassName UserOrderServiceImpl
 * @Description TODO
 * @Author Admin
 * @Date 2023/7/14 13:22
 * @Version 1.0
 **/
@Service
public class UserOrderServiceImpl implements IUserOrderService {

    @Resource
    private TudaOrderMapper orderMapper;
    @Resource
    private TudaOrderTransferMapper orderTransferMapper;
    @Resource
    private WeixinPayConfig weixinPayConfig;
    @Resource
    private Environment environment;
    @Resource
    private TudaAppletUserMapper appletUserMapper;
    @Resource
    private ISysUserService sysUserService;
    @Resource
    private TudaOrderTransferMapper tudaOrderTransferMapper;
    @Resource
    private ITudaOrderRecordService orderRecordService;

    private static final Logger logger = LoggerFactory.getLogger(UserOrderServiceImpl.class);
    @Override
    public void wxMiniNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("这里是回调 =======================================================");
        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        logger.info("微信返回的xml =========" + notityXml);
        String resXml = "";
        Map<String, String> parameters = WXPayUtil.xmlToMap(notityXml);
        String returnCode = parameters.get("return_code");
        if ("SUCCESS".equals(returnCode)) {
            //验证签名是否正确（根据订单信息重新获取签名）
            String sign = WXPayUtil.generateSignature(parameters, environment.getProperty("pay.weixin.mini.key"));
            //根据微信官网的介绍，此处不仅对回调的参数进行验签，还需要对返回的金额与系统订单的金额进行比对等
            if (sign.equals(parameters.get("sign"))) {
                //订单号id
                String outTradeNo = parameters.get("out_trade_no");
                //微信支付订单号
                String transactionId = parameters.get("transaction_id");
                BigDecimal payAmount = new BigDecimal(parameters.get("total_fee")).divide(new BigDecimal(100));
                // 更改订单为已支付状态
                paySuccess(outTradeNo, payAmount, transactionId);
                logger.info("成功回调 outTradeNo==" + outTradeNo + ";/transactionId==" + transactionId);
                //通知微信服务器已经支付成功
                resXml = "<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> </xml>";
            } else {
                String outTradeNo = parameters.get("out_trade_no");
                payFail(outTradeNo);
                logger.info("微信支付回调失败!签名不一致");
            }
        } else {
            resXml = "<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[报文为空]]></return_msg> </xml> ";
        }
        logger.info("微信支付回调数据结束");
        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

    /**
     * 支付成功
     * @param tradeNo
     * @param totalAmount
     * @param transactionId
     */
    public void paySuccess(String tradeNo, BigDecimal totalAmount, String transactionId){
        OrderTInfoResult order = orderMapper.queryOrderByOrderNum(tradeNo);
       if(ToolUtil.isNotEmpty(order)){
           TudaOrder tudaOrder = EntityConvertUtils.convertAToB(order, TudaOrder.class);
           tudaOrder.setOrderType(OrderType.ORDER_6.getCode());
           tudaOrder.setTransactionId(transactionId);
           orderMapper.updateTudaOrder(tudaOrder);
       }
    }

    /**
     * 支付失败
     * @param outTradeNo
     */
    public void payFail(String outTradeNo){

    }

    @Override
    public R<OrderInfoResult> getList(QueryOrderListParam param) {
        TudaAppletUser appletUser = appletUserMapper.selectTudaAppletUserById(param.getUserId());
        if(ToolUtil.isEmpty(appletUser)){
            return R.fail("信息已失效，请重新登录");
        }
        param.setSalesmanPhone(appletUser.getPhone());
        List<OrderListResult> orderList = null;
        if(appletUser.getUserType() > 0){ // 业务员
            orderList = orderMapper.getList(param);
//        } else if (appletUser.getUserType() == 2) { // 经办人
//            orderList = orderMapper.getHandledByList(param, appletUser.getPhone());
        }
        if(appletUser.getUserType() == 0) {// 管理员
            orderList = orderMapper.getDriverList(param, appletUser.getPhone());
        }
        OrderInfoResult result = new OrderInfoResult();
        for(OrderListResult o : orderList){
            List<OrderTransferResult> t = orderTransferMapper.getOrderTransferList(o.getId());
            o.setRouteList(t);
        }
        result.setResults(orderList);
        result.setCount(orderMapper.getListCount(param, appletUser.getUserType()));
        return R.ok(result);
    }

    @Override
    public R<OrderInfoResult> getUserList(QueryUserOrderListParam param) {
        TudaAppletUser appletUser = appletUserMapper.selectTudaAppletUserById(param.getUserId());
        if(ToolUtil.isEmpty(appletUser)){
            return R.fail("信息已失效，请重新登录");
        }
        param.setSalesmanPhone(appletUser.getPhone());
        OrderInfoResult result = new OrderInfoResult();
        List<OrderListResult> orderList = orderMapper.getUserList(param, appletUser.getUserType());
        for(OrderListResult o : orderList){
            List<OrderTransferResult> t = orderTransferMapper.getOrderTransferList(o.getId());
            o.setRouteList(t);
        }
        result.setResults(orderList);
        result.setCount(orderMapper.getUserListCount(param, appletUser.getUserType()));
        return R.ok(result);
    }

    @Override
    public R<OrderTInfoResult> getInfo(GetOrderInfoParam param) {
        OrderTInfoResult result = orderMapper.queryOrderInfoById(param.getOrderId());
        if(ToolUtil.isNotEmpty(result)){
            result.setTransfer(orderTransferMapper.queryOrderTransferByOrderId(result.getId()));
            result.setSupplement(orderTransferMapper.queryByOrderId(result.getId()));
        }
        return R.ok(result);
    }

    @Override
    public R<NewOrderListResult> getOrderTransferList(Long orderId) {
        NewOrderListResult result = orderMapper.getOrderTransferList(orderId);
        if(ToolUtil.isNotEmpty(result)){
            List<OrderTransferResult> t = orderTransferMapper.getOrderTransferList(orderId);
            result.setRouteList(t);
        }
        return R.ok(result);
    }

    @Override
    public R updateTransfer(OrderTransferResult orderTransfer) {
        orderTransfer.setTransitBranch(null);
        orderTransferMapper.updateTransfer(orderTransfer);
        return R.ok();
    }

    @Override
    public R addOrder(AddOrderParam params) {
        TudaOrder order = EntityConvertUtils.convertAToB(params, TudaOrder.class);
//        TudaAppletUser appletUser = appletUserMapper.selectTudaAppletUserById(order.getUserId());
//        order.setUserName(ToolUtil.isEmpty(appletUser) ? null : appletUser.getNickName());
        order.setCarImgs(params.getCarImgs().toString());
        order.setContractImgs(params.getContractImgs().toString());
        order.setOrderNum(StringUtils.getOrderNo());
        order.setOrderType(OrderType.ORDER_3.getCode());
        int r = orderMapper.insertTudaOrder(order);
        if(r > 0){
            if (r > 0 && (order.getPayType().equals(OrderPayType.PAY_TYPE_2.getCode()) || order.getPayType().equals(OrderPayType.PAY_TYPE_4.getCode()))){
                orderRecordService.insertOrderRecord(order.getId(), OrderPayType.getNameByCode(order.getPayType()), order.getFreightAmount(),null, null);
            }
            if(order.getPaidAmount().compareTo(new BigDecimal(0.00)) == 1){
                orderRecordService.insertOrderRecord(order.getId(), "预付款", order.getPaidAmount(),null, null);
            }
            insertT(order.getId());
            return R.ok();
        }
        return R.fail("建单失败请重试！");
    }

    public void insertT(Long orderId){
        int i = 0;
        while (i < 2) {
            i++;
            TudaOrderTransfer tudaOrderTransfer = new TudaOrderTransfer();
            tudaOrderTransfer.setOrderId(orderId);
            tudaOrderTransferMapper.insertTudaOrderTransfer(tudaOrderTransfer);
        }
    }

    @Override
    public R<List<UserListResult>> queryUserInfo() {
        List<SysUser> sysUsers = sysUserService.queryUserByRole();
        List<UserListResult> userListResults = new ArrayList<>();
        for (SysUser user : sysUsers) {
            UserListResult result = new UserListResult();
            result.setUserName(user.getUserName());
            result.setSalesmanPhone(user.getPhonenumber());
            userListResults.add(result);
        }
        return R.ok(userListResults);
    }

    @Override
    public R carOk(CarOkParam param) {
        if(ToolUtil.isNotEmpty(param) && ToolUtil.isNotEmpty(param.getTransporter())){
            TudaOrderTransfer orderTransfer = EntityConvertUtils.convertAToB(param, TudaOrderTransfer.class);
            orderTransfer.setCreateTime(new Date());
            orderTransfer.setType(2);
            orderTransferMapper.save(orderTransfer);
        }
        TudaOrder order = orderMapper.selectTudaOrderById(param.getOrderId());
        if(ToolUtil.isEmpty(order)){
            return R.fail("运单信息不存在");
        }
        order.setOrderType(OrderType.ORDER_2.getCode());
        orderMapper.updateTudaOrder(order);
        return R.ok();
    }

    @Override
    public R confirm(CarOkParam param) {
        if(ToolUtil.isNotEmpty(param) && ToolUtil.isNotEmpty(param.getTransporter())){
            TudaOrderTransfer orderTransfer = EntityConvertUtils.convertAToB(param, TudaOrderTransfer.class);
            orderTransfer.setType(2);
            orderTransferMapper.save(orderTransfer);
        }
        TudaOrder order = orderMapper.selectTudaOrderById(param.getOrderId());
        if(ToolUtil.isEmpty(order)){
            return R.fail("运单信息不存在");
        }
        order.setOrderType(OrderType.ORDER_3.getCode());
        orderMapper.updateTudaOrder(order);
        return R.ok();
    }

    @Override
    public R confirmSignFor(GetOrderInfoParam param) {
       TudaOrder order = orderMapper.selectTudaOrderById(param.getOrderId());
        if(ToolUtil.isEmpty(order)){
            return R.fail("订单不存在");
       }
       TudaOrderTransfer orderTransfer = orderTransferMapper.queryOrderInfoById(param.gettId());
       if(ToolUtil.isNotEmpty(orderTransfer) && orderTransfer.getState() == 1){
           orderTransferMapper.updateState(param.gettId());
           return R.ok();
       }
       return R.fail("请勿重复确认");
    }


    public  R endSignFor(GetOrderInfoParam param){
        TudaOrder order = orderMapper.selectTudaOrderById(param.getOrderId());
        if(ToolUtil.isEmpty(order)){
            return R.fail("订单不存在");
        }
        order.setOrderType(OrderType.ORDER_5.getCode());
        if(orderMapper.updateTudaOrder(order) > 0){
            return R.ok();
        }
        return R.fail("签收失败，请重试");
    }

    /**
     * 生成支付串
     * @param param 请求参数
     * @return
     * @throws Exception
     */
    public R payMoney(PayMoneyParam param) {
        BigDecimal price = new BigDecimal(0.01);
        OrderTInfoResult order = orderMapper.queryOrderByOrderNum(param.getOrderNum());
        if(ToolUtil.isEmpty(order)){
            return R.fail("订单不存在");
        }
        if(order.getOrderType() == 6){
            return R.fail("订单已支付，请勿重复付款");
        }
        String lx = order.getOrigin()+"到"+order.getDest()+"运费款";
//        price = order.getFreightAmount().subtract(order.getPaidAmount());
        PayOrder payOrder = new PayOrder(lx, lx, price, order.getOrderNum());
        payOrder.setTransactionType(WxTransactionType.JSAPI);
        payOrder.setOpenid(param.getOpenId());
        //小程序支付
        Map orderInfo = weixinPayConfig.getPayServiceMINI().orderInfo(payOrder);
        RedisUtil.setForTimeMIN("wm:" + order.getOrderNum(), orderInfo.get("package").toString(), 20);
        return  R.ok(orderInfo, "小程序支付", order.getOrderNum());
    }


    public R toWxQrPay(PayMoneyParam param) {
        BigDecimal price = new BigDecimal("0.01");
        OrderTInfoResult order = orderMapper.queryOrderByOrderNum(param.getOrderNum());
        if(ToolUtil.isEmpty(order)){
            return R.fail("订单不存在");
        }
        if(order.getOrderType() == 6){
            return R.fail("订单已支付，请勿重复付款");
        }
        String lx = order.getOrigin()+"到"+order.getDest();
//        price = order.getFreightAmount().subtract(order.getPaidAmount());
        String codeUrl = weixinPayConfig.getPayServiceAPP().genQrPayCodeUrl(new PayOrder(lx+"运费款", "摘要", null == price ? new BigDecimal(0.01) : price,
                param.getOrderNum(), WxTransactionType.NATIVE));
        Map<String, Object> map = new HashMap<>();
        map.put("codeUrl", codeUrl);
        map.put("price", price);
        return  R.ok(map);
    }

    @Override
    public R queryOrderPayType(PayMoneyParam param) {
        Map<String, Object> map = new HashMap<>();
        OrderTInfoResult order = orderMapper.queryOrderByOrderNum(param.getOrderNum());
        if (ToolUtil.isNotEmpty(order)){
            if(order.getOrderType() != 6){
                map.put("orderType", 0);
            }else {
                map.put("orderType", 1);
            }
        }
        return R.ok(map);
    }


}
